package com.activenetwork.smlite.page.rfp.RfpMaintenanceView;

import java.io.File;
import java.util.List;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.activenetwork.custom.other.XCheckbox;
import com.activenetwork.custom.uielement.UIElement;
import com.activenetwork.custom.uielement.decorate.InJson;
import com.activenetwork.schema.model.rfp.AdditionalRequestInfoType;
import com.activenetwork.schema.model.rfp.RfpAdditionalRequestType;
import com.activenetwork.smlite.page.rfp.RfpBasicsSubview;
import com.activenetwork.smlite.snippet.RfpDateCalculator;
import com.activenetwork.smlite.snippet.RfpDay;
import com.activenetwork.util.DateUtil;
import com.activenetwork.util.EnvContext;
import com.activenetwork.util.FileUtil;
import com.activenetwork.util.PageLoader;
import com.activenetwork.util.RandomString;
import com.activenetwork.util.WaitUtil;
import com.activenetwork.util.dropdownmenu.DropdownMenu;
import com.activenetwork.util.dropdownmenu.TimeDropdownMenu;
import com.google.common.collect.Lists;

public class RfpAdditionalRequest extends RfpBasicsSubview {
	private Logger logger = LoggerFactory.getLogger(RfpAdditionalRequest.class);
	
	@InJson
	private UIElement additionInformationHeader;
	@InJson
	private UIElement additionalRequestComment;
	@InJson
	private UIElement addNewAttach;
	
	private String getCommentDisplayStatus(){
		WebDriver driver = EnvContext.webDriverTL.get();
		By statusBy = By.cssSelector(".autotest-collapsibleSection-RfpAdditionalRequestsSubview-aradditioninfosection .nexus-section-body");
		WebElement div = driver.findElement(statusBy);
		return div.getAttribute("class").trim();
	}
	
	/**
	 * Setup the comment
	 * @param comment
	 * @return
	 */
	public RfpAdditionalRequest setComment(String comment){
		additionalRequestComment.clear();
		additionalRequestComment.sendKeys(comment);
		return this;
	}
	
	/**
	 * Show additional information
	 * @return
	 */
	public RfpAdditionalRequest showAdditionalInformation(){
		if(getCommentDisplayStatus().contains("hide")){
			additionInformationHeader.click();
			return PageLoader.load(RfpAdditionalRequest.class);
		}else{
			return this;
		}
	}
	/**
	 * Hide additional information
	 * @return
	 */
	public RfpAdditionalRequest hideAdditionalInformation(){
		if(!getCommentDisplayStatus().contains("hide")){
			additionInformationHeader.click();
			return PageLoader.load(RfpAdditionalRequest.class);
		}else{
			return this;
		}
	}
	/**
	 * Parse additional request category and return one kind of additional request data
	 * category: pre - stands for preceding shoulder additional request
	 * category: post - stands for following shoulder additional request
	 * category: origin - stands for original shoulder additional request
	 * @param addtRequest
	 * @param category
	 * @return
	 */
	private List<AdditionalRequestInfoType> getAdditionalRequestData(RfpAdditionalRequestType addtRequest, String category, int rowIndex, RfpDateCalculator calculator){
		// Get all the additional request xml node
		List<AdditionalRequestInfoType> addtRqts = addtRequest.getAdditionalRequestInfo();
		List<AdditionalRequestInfoType> targetList = Lists.newArrayList();
		// Loop to get the corresponding food beverage node
		// Recalculate each day's day index to match the actual row index of the day on the page
		int matchRowIndex = -1;
		for(AdditionalRequestInfoType aq : addtRqts){
			if(category.equals("pre")){
				matchRowIndex =  aq.getDayIndex();
			}
			if(category.equals("origin")){
				matchRowIndex =  aq.getDayIndex() + calculator.rfpLength("pre");
			}
			if(category.equals("post")){
				matchRowIndex =  aq.getDayIndex() + calculator.rfpLength("pre") + calculator.rfpLength("origin");
			}
			if(aq.getCategory().equals(category) && matchRowIndex == rowIndex){
				targetList.add(aq);
			}
		}
		return targetList;
	}
	/**
	 * Setup preceding additional request days 
	 * @param addtRequest
	 * @param calculator
	 * @return
	 */
	public RfpAdditionalRequest setPrecedingShoulderAdditionalRequest(RfpAdditionalRequestType addtRequest, RfpDateCalculator calculator){
		List<RfpDay> precedingDays = calculator.getRfpDays("pre");
		RfpAdditionalRequest instance = PageLoader.load(RfpAdditionalRequest.class);
		for(RfpDay rfpday : precedingDays){
			// Get this day additional request data
			List<AdditionalRequestInfoType> ar_oneday_data = getAdditionalRequestData(addtRequest, "pre", rfpday.getRowIndex(), calculator);
			// Setup food beverage for this day
			for(AdditionalRequestInfoType data : ar_oneday_data){
				instance = instance.setAdditionalRequest(data, rfpday.getRowIndex()-1);
			}
		}
		return instance;
	}
	/**
	 * Setup origin additional request days
	 * @param addtRequest
	 * @param calculator
	 * @return
	 */
	public RfpAdditionalRequest setOriginAdditionalRequest(RfpAdditionalRequestType addtRequest, RfpDateCalculator calculator){
		List<RfpDay> originDays = calculator.getRfpDays("origin");
		RfpAdditionalRequest instance = PageLoader.load(RfpAdditionalRequest.class);
		for(RfpDay rfpday : originDays){
			// Get this day additional request data
			List<AdditionalRequestInfoType> ar_oneday_data = getAdditionalRequestData(addtRequest, "origin", rfpday.getRowIndex(), calculator);
			// Setup food beverage for this day
			for(AdditionalRequestInfoType data : ar_oneday_data){
				instance = instance.setAdditionalRequest(data, rfpday.getRowIndex()-1);
			}
		}
		return instance;
	}
	/**
	 * Setup following additional request days
	 * @param addtRequest
	 * @param calculator
	 * @return
	 */
	public RfpAdditionalRequest setFollowingShoulderAdditionalRequest(RfpAdditionalRequestType addtRequest, RfpDateCalculator calculator){
		List<RfpDay> followingDays = calculator.getRfpDays("post");
		RfpAdditionalRequest instance = PageLoader.load(RfpAdditionalRequest.class);
		for(RfpDay rfpday : followingDays){
			// Get this day additional request data
			List<AdditionalRequestInfoType> ar_oneday_data = getAdditionalRequestData(addtRequest, "post", rfpday.getRowIndex(), calculator);
			// Setup food beverage for this day
			for(AdditionalRequestInfoType data : ar_oneday_data){
				instance = instance.setAdditionalRequest(data, rfpday.getRowIndex()-1);
			}
		}
		return instance;
	}
	/**
	 * Setup one additional request record under one random day and copy to all days
	 * @param addtRequest
	 * @param calculator
	 * @return
	 */
	public RfpAdditionalRequest setCopyAllDayAdditionalRequest(RfpAdditionalRequestType addtRequest, RfpDateCalculator calculator){
		RfpAdditionalRequest instance = PageLoader.load(RfpAdditionalRequest.class);
		List<AdditionalRequestInfoType> ardata = addtRequest.getAdditionalRequestInfo();
		for(AdditionalRequestInfoType ar : ardata){
			if(ar.getCategory().equals("all")){
				instance = instance.setAdditionalRequest(ar, RandomString.generateRandomInt(calculator.rfpLength()));
			}
		}
		return instance;
	}
	
	public RfpAdditionalRequest setAdditionalRequest(AdditionalRequestInfoType additionRequest, int dayIndex){
		// find the root div for each day
		WebDriver driver = EnvContext.webDriverTL.get();
		By rootDivBy = By.cssSelector("div.autotest-grid-RfpAdditionalRequestsSubview-rfpadditionalrequestsgrid[data-nexus-groupgrid-index='" + dayIndex + "']");
		WebElement rootDiv = driver.findElement(rootDivBy);
		
		String dayInfo = rootDiv.findElement(By.xpath(".//div[@class='section-header']//h3")).getText().trim();
		String category = additionRequest.getCategory();
		logger.info("Start set " + category + " day : " + dayInfo + " additional request");
		
		// click add event additional request
		clickAddAdditionalRequest(rootDiv);
		
		// Setup Type
		setType(rootDiv, additionRequest.getRequestType());

		// Setup start time
		setStartTime(rootDiv, DateUtil.toTimeOption(additionRequest.getStartTime()));
		
		// Setup end time
		setEndTime(rootDiv, DateUtil.toTimeOption(additionRequest.getEndTime()));
		
		// Setup attendee number
		setAttendeeNumber(rootDiv, String.valueOf(additionRequest.getAttendeeNumber()));
		
		// Setup room setup style
		setRoomSetupStyle(rootDiv, additionRequest.getRoomSetupStyle().value());
		
		// Setup 24hr hold
		setTwentyFourHourHold(rootDiv, additionRequest.isTwentyFourHourHold());
		
		// Set copy all if necessary
		if(additionRequest.getCategory().equals("all")){
			setCopyAll(rootDiv);
		}
		// save the event food & beverage
		clickSaveAdditionalRequest(rootDiv);
		
		logger.info("Set " + category + " day : " + dayInfo + " additional request done");
		return PageLoader.load(RfpAdditionalRequest.class);
	}
	
	public void clickAddAdditionalRequest(WebElement rootDiv){
		WaitUtil waitUtil = new WaitUtil();
		logger.debug("click add button");
		WebElement add = rootDiv.findElement(By.xpath(".//button[contains(@class, 'autotest-gridaction-rfpadditionalrequestssubview-rfpadditionalrequestsgrid')]"));
		add.click();
		waitUtil.wait(500);
	}
	
	public void clickSaveAdditionalRequest(WebElement rootDiv){
		WaitUtil waitUtil = new WaitUtil();
		logger.debug("Save the additional request");
		WebElement save = rootDiv.findElement(By.xpath(".//button[contains(@class,'autotest-ioasaveaction-additionalrequestsform')]"));
		save.click();
		waitUtil.wait(500);
	}
	
	public void setType(WebElement rootDiv, String typeValue){
		logger.debug("Setup Type");
		WebElement type = rootDiv.findElement(By.xpath(".//div[contains(@class,'autotest-combo-AdditionalRequestsForm-eventtype')]//input"));
		DropdownMenu mealTypeDropdown = new DropdownMenu(type);
		mealTypeDropdown.select(typeValue);
	}
	
	public void setStartTime(WebElement rootDiv, String time){
		logger.debug("Set start time");
		WebElement startTime = rootDiv.findElement(By.xpath(".//div[contains(@class,'autotest-time-AdditionalRequestsForm-starttime')]//input"));
		DropdownMenu startTimeDropdown = new TimeDropdownMenu(startTime);
		startTimeDropdown.select(time);
	}
	
	public void setEndTime(WebElement rootDiv, String time){
		logger.debug("Set end time");
		WebElement endTime = rootDiv.findElement(By.xpath(".//div[contains(@class,'autotest-time-AdditionalRequestsForm-endtime')]//input"));
		DropdownMenu endTimeDropdown = new TimeDropdownMenu(endTime);
		endTimeDropdown.select(time);
	}
	
	public void setAttendeeNumber(WebElement rootDiv, String number){
		logger.debug("Set number of attendee");
		WebElement attendee = rootDiv.findElement(By.xpath(".//div[contains(@class,'autotest-integer-AdditionalRequestsForm-attendeequantity')]//input"));
		attendee.click();
		attendee.clear();
		attendee.sendKeys(number);
	}
	
	public void setRoomSetupStyle(WebElement rootDiv, String style){
		logger.debug("Set room setup style");
		WebElement rootSetupStyle = rootDiv.findElement(By.xpath(".//div[contains(@class,'autotest-combo-AdditionalRequestsForm-setuptype')]//input"));
		DropdownMenu rootSetupStyleDropdown = new DropdownMenu(rootSetupStyle);
		rootSetupStyleDropdown.select(style);
	}
	
	public void setTwentyFourHourHold(WebElement rootDiv, boolean hold){
		logger.debug("Set 24hr hold");
		WebElement twentyFour = rootDiv.findElement(By.xpath(".//div[contains(@class,'autotest-checkbox-AdditionalRequestsForm-hold')]//input"));
		XCheckbox checkbox = new XCheckbox(twentyFour);
		if(hold){
			logger.debug("Set 24 hours hold - ON");
			checkbox.checkON();
		}else{
			logger.debug("Set 24 hours hold - OFF");
			checkbox.checkOFF();
		}
	}
	
	public void setCopyAll(WebElement rootDiv){
		logger.debug("Check on CopyAll");
		WebElement copyAll = rootDiv.findElement(By.xpath(".//div[contains(@class,'autotest-checkbox-AdditionalRequestsForm-copyadditionalrequeststoall')]//input"));
		XCheckbox checkbox = new XCheckbox(copyAll);
		checkbox.checkON();
	}
	
	public RfpAdditionalRequest clickAddNewAttach(){
		addNewAttach.click();
		return PageLoader.load(RfpAdditionalRequest.class);
	}
	
	public RfpAdditionalRequest setAttachment(String filepath, String filedesc){
		WebDriver driver = EnvContext.webDriverTL.get();
		WebElement fileUpload = driver.findElement(By.cssSelector(".autotest-html-fileuploadioa input[name='fileName1']"));
		if(filepath.length()==0){ // create temporary file
			File file = FileUtil.createTempFile("uploadfile"+"-"+RandomString.generateRandomString(5), "txt", RandomString.generateRandomString(400), new File(System.getProperty("user.dir")));
			fileUpload.sendKeys(file.getAbsolutePath());
			file.deleteOnExit();
		}else{
			fileUpload.sendKeys(filepath);
		}
		WebElement fileDesc = driver.findElement(By.cssSelector(".autotest-html-fileuploadioa input[name='fileDescription1']"));
		fileDesc.sendKeys(filedesc);
		return this;
	}
	
	public RfpAdditionalRequest clickUploadAttachment(){
		WebDriver driver = EnvContext.webDriverTL.get();
		driver.findElement(By.cssSelector("button.autotest-ioafileuploadaction-fileuploadioa")).click();
		return PageLoader.load(RfpAdditionalRequest.class);
	}
	
	
	
}
